package cz.data.common.elastic;

import cz.data.common.elastic.manage.EsManageFactory;
import cz.data.common.support.YamlPropertySourceFactory;
import cz.data.common.support.db.DbType;
import cz.data.common.support.db.manage.DbManageRegistry;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;

@Configuration
@PropertySource(value = "classpath:elastic-setting.yml", factory = YamlPropertySourceFactory.class, encoding = "UTF-8")
@EnableConfigurationProperties(ElasticsearchProperties.class)
public class ElasticSearchConfiguration extends AbstractElasticsearchConfiguration {

    @Resource
    ElasticsearchProperties properties;

    @Bean
    @Override
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(properties.getUris().toArray(new String[0]))
                .withBasicAuth(properties.getUsername(), properties.getPassword())
                .build();

        return RestClients.create(clientConfiguration).rest();
    }

    @Bean(name = {"elasticsearchOperations", "elasticsearchTemplate"})
    @Override
    public ElasticsearchRestTemplate elasticsearchOperations(ElasticsearchConverter elasticsearchConverter,
                                                             RestHighLevelClient elasticsearchClient) {
        return (ElasticsearchRestTemplate) super.elasticsearchOperations(elasticsearchConverter, elasticsearchClient);
    }

    @PreDestroy
    public void destroy() {
        CacheClientBean.shutdown();
    }

    static {
        DbManageRegistry.registry(new EsManageFactory(), DbType.ELASTICSEARCH);
    }
}
